package com.jzoom.zoom.admin.rules;

import com.jzoom.zoom.admin.utils.JsUtils;
import com.jzoom.zoom.caster.Caster;
import com.jzoom.zoom.common.expression.Symbol;
import com.jzoom.zoom.common.utils.MapUtils;
import org.codehaus.jackson.annotate.JsonIgnore;

import java.util.Map;
import java.util.regex.Pattern;

/**
 * 数据库入库规则
 */
public class Rules {

    /**
     * 随时可以还原
     *
     * @param <T>
     */
    public static abstract class AbstractRule<T> implements Validate<T> {
        public String getMessage() {
            return message;
        }

        public void setMessage(String message) {
            this.message = message;
        }

        protected String message;
        protected String type;

        public String getType() {
            return type;
        }

        public void setType(String type) {
            this.type = type;
        }

        AbstractRule(String message, String type) {
            this.message = message;
            this.type = type;
        }

        AbstractRule() {

        }


    }


    /**
     * 至于其他奇葩的规则，需要自己手动写js
     * 在服务端也执行对应的js
     */

    public static class JsRule<T> extends AbstractRule<T> {

        public String getJs() {
            return js;
        }

        public void setJs(String js) {
            this.js = js;
        }

        private String js;

        public JsRule(String message, String js) {
            super(message, "js");
            this.js = js;
        }

        public JsRule() {

        }

        @Override
        public String validate(T data, Object value) {
            Object result = JsUtils.execute(js, MapUtils.asMap("message", message), data, value);
            if (result instanceof String) {
                return (String) result;
            }

            return null;

        }

    }

    public static class MapCompareRule extends CompareRule<Map<String, Object>> {
        public MapCompareRule(String message, String target, Symbol symbol) {
            super(message, target, symbol);
        }

        @Override
        protected Object get(Map<String, Object> data, String target) {
            return data.get(target);
        }
    }

    /**
     * 这个涉及两个字段比较，需要从数据中取出对应的值
     *
     * @param <T>
     */
    public static abstract class CompareRule<T> extends AbstractRule<T> {

        //比较目标的key
        private String target;


        // 比较运算符
        private Symbol symbol;

        public String getTarget() {
            return target;
        }

        public void setTarget(String target) {
            this.target = target;
        }

        public Symbol getSymbol() {
            return symbol;
        }

        public void setSymbol(Symbol symbol) {
            this.symbol = symbol;
        }

        public CompareRule() {

        }


        public CompareRule(String message, String target, Symbol symbol) {
            super(message, "compare");
            this.target = target;
            this.symbol = symbol;
        }

        @Override
        public String validate(T data, Object value) {
            if (!this.symbol.compare((Comparable) value, (Comparable) get(data, target))) {
                return message;
            }
            return null;
        }

        protected abstract Object get(T data, String target);

    }

    public static class LengthRule<T> extends AbstractRule<T> {

        private int min;
        private int max;

        public int getMin() {
            return min;
        }

        public void setMin(int min) {
            this.min = min;
        }

        public int getMax() {
            return max;
        }

        public void setMax(int max) {
            this.max = max;
        }

        LengthRule(String message, int min, int max) {
            super(message, "length");
            this.min = min;
            this.max = max;
        }

        //长度校验
        @Override
        public String validate(T data, Object value) {
            if (value == null) {
                //如果是空的，由其他规则限制，否则不做判断
                return null;
            }

            String str = Caster.to(value, String.class);

            if (str.length() >= min && str.length() <= max)
                return null;

            return message;
        }
    }

    /**
     * 自然是只能对数字进行校验了
     *
     * @param <T>
     */
    public static class MaxMinRule<T> extends AbstractRule<T> {

        private Double max;
        private Double min;

        public MaxMinRule(String message, Object min, Object max) {
            super(message, "max");
            this.max = Caster.to(max, Double.class);
            this.min = Caster.to(min, Double.class);
        }

        @Override
        public String validate(T data, Object value) {
            if (value == null) {
                //如果是空的，由其他规则限制，否则不做判断
                return null;
            }
            Double target = Caster.to(value, Double.class);

            if (this.max != null && this.max.compareTo(target) < 0) {

                return message;

            }

            if (this.min != null && this.min.compareTo(target) > 0) {
                return message;
            }

            return null;


        }
    }

    public static class RequiredRule<T> extends AbstractRule<T> {

        public RequiredRule(String message) {
            super(message, "required");
        }

        @Override
        public String validate(T data, Object value) {
            if (value == null) {
                return message;
            }

            if (value instanceof String && ((String) value).isEmpty()) {
                return message;
            }

            return null;
        }
    }

    public static class PatternRule<T> extends AbstractRule<T> {
        public String getPattern() {
            return pattern;
        }

        public void setPattern(String pattern) {
            this.pattern = pattern;
        }

        private String pattern;

        @JsonIgnore
        private Pattern _pattern;

        public PatternRule(String message, String pattern) {
            super(message, "pattern");
            this.pattern = pattern;
        }

        public PatternRule() {

        }


        @Override
        public String validate(T data, Object value) {
            if (value == null) {
                //如果是空的，由其他规则限制，否则不做判断
                return null;
            }
            String str = Caster.to(value, String.class);
            Pattern _pattern = this._pattern;
            if (_pattern == null) {
                _pattern = Pattern.compile(pattern);
                this._pattern = _pattern;
            }
            if (_pattern.matcher(str).matches()) {
                return null;
            }
            return message;
        }
    }


}
